﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NHibernate;
using VegetableStore.Providers;
using VegetableStore.Util;
using VegetableStore.Domains;
using System.Web.Script.Serialization;
using VegetableStore.Models;
using System.Globalization;

namespace VegetableStore.Controllers
{
    public class PurchaseController : Controller
    {
        private ISession nhibernateSession;
        private JavaScriptSerializer serializer;
        private const string TRUE = "1";
        private const string FALSE = "0";

        public PurchaseController()
        {
            nhibernateSession = SessionProvider.Instance.GetSession();
            serializer = new JavaScriptSerializer();
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult InsertShoppingBasket(string token, int? productId, int? quantity)
        {
            try
            {
                if (productId == null) return Json(new { result = "FAILURE", msg = "productId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (quantity == null) return Json(new { result = "FAILURE", msg = "quantity가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Shoppingbasket shoppingBasketAlias = null;
                Users usersAlias = null;
                Product productAlias = null;
                Product product = nhibernateSession.Get<Product>(productId);
                if (product == null) return Json(new { result = "FAILURE", msg = "Id가 " + productId + "인 상품이 없습니다." }, JsonRequestBehavior.AllowGet);
                if (!product.UseYN)
                {
                    return Json(new { result = "FAILURE", msg = product.Name + "은 마감된 상품입니다." }, JsonRequestBehavior.AllowGet);
                }
                
                Shoppingbasket existingShoppingBasket = nhibernateSession.QueryOver<Shoppingbasket>(() => shoppingBasketAlias)
                    .JoinAlias(() => shoppingBasketAlias.Product, () => productAlias)
                    .JoinAlias(() => shoppingBasketAlias.Users, () => usersAlias)
                    .WhereRestrictionOn(() => productAlias.Id).IsLike(productId)
                    .WhereRestrictionOn(() => usersAlias.Token).IsLike(token)
                    .List()
                    .FirstOrDefault();

                if (existingShoppingBasket == null)
                {
                    // 추가
                    Users user = nhibernateSession.CreateQuery("from Users where token = :token")
                        .SetString("token", token)
                        .UniqueResult<Users>();
                    Shoppingbasket shoppingbasket = new Shoppingbasket
                    {
                        Users = user,
                        Product = nhibernateSession.Load<Product>(productId),
                        Quantity = quantity
                    };
                    using (var tx = nhibernateSession.BeginTransaction())
                    {
                        try
                        {
                            nhibernateSession.Save(shoppingbasket);
                            nhibernateSession.Flush();
                            tx.Commit();
                        }
                        catch (Exception te)
                        {
                            tx.Rollback();
                            SessionProvider.Instance.CloseSession();
                            throw te;
                        }
                    }
                }
                else
                {
                    //업데이트(개수만 추가)
                    existingShoppingBasket.Quantity = existingShoppingBasket.Quantity + quantity;
                    using (var tx = nhibernateSession.BeginTransaction())
                    {
                        try
                        {
                            nhibernateSession.Update(existingShoppingBasket);
                            nhibernateSession.Flush();
                            tx.Commit();
                        }
                        catch (Exception te)
                        {
                            tx.Rollback();
                            SessionProvider.Instance.CloseSession();
                            throw te;
                        }
                    }
                }                
                return Json(new { result = "SUCCESS" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetShoppingBasket(string token)
        {
            try
            {
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);
                
                IList<Shoppingbasket> shoppingBasketList = nhibernateSession.QueryOver<Shoppingbasket>()
                    .JoinQueryOver<Users>(x => x.Users)
                    .Where(x => x.Token == token)
                    .List<Shoppingbasket>();

                return Json(new { result = "SUCCESS", data = shoppingBasketList }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult DeleteShoppingBasket(string token, string productIdList)
        {
            try
            {
                if (productIdList == null) return Json(new { result = "FAILURE", msg = "productIdList가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Shoppingbasket shoppingBasketAlias = null;
                Users usersAlias = null;
                Product productAlias = null;

                string[] productIdStringList = productIdList.Split(',');

                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        foreach (string productIdString in productIdStringList)
                        {
                            int productId = Int32.Parse(productIdString);
                            Shoppingbasket shoppingBasket = nhibernateSession.QueryOver<Shoppingbasket>(() => shoppingBasketAlias)
                                .JoinAlias(() => shoppingBasketAlias.Product, () => productAlias)
                                .JoinAlias(() => shoppingBasketAlias.Users, () => usersAlias)
                                .WhereRestrictionOn(() => productAlias.Id).IsLike(productId)
                                .WhereRestrictionOn(() => usersAlias.Token).IsLike(token)
                                .List()
                                .FirstOrDefault();
                            if (shoppingBasket == null)
                            {
                                tx.Rollback();
                                return Json(new { result = "FAILURE", msg = "장바구니에 id가 " + productId + "인 상품이 없습니다." }, JsonRequestBehavior.AllowGet);
                            }
                            nhibernateSession.Delete(shoppingBasket);
                        }
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        throw te;
                    }

                }
                return Json(new { result = "SUCCESS" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult InsertOrdersFromShoppingBasket(string token, string shoppingBasketIdList)
        {
            try
            {
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Users user = nhibernateSession.QueryOver<Users>()
                    .Where(x => x.Token == token)
                    .List()
                    .FirstOrDefault();
                int[] orderIdList;
                IList<Shoppingbasket> shoppingBasketList;
                if (shoppingBasketIdList != null)
                {
                    string[] shoppingBasketIdStringList = shoppingBasketIdList.Split(',');
                    shoppingBasketList = new List<Shoppingbasket>();
                    foreach (string shoppingBasketIdString in shoppingBasketIdStringList)
                    {
                        int shoppingBasketId = Int32.Parse(shoppingBasketIdString);
                        Shoppingbasket shoppingBasket = nhibernateSession.Get<Shoppingbasket>(shoppingBasketId);
                        if (shoppingBasket == null) return Json(new { result = "FAILURE", msg = "id가 " + shoppingBasketId + "인 장바구니가 없습니다." }, JsonRequestBehavior.AllowGet);
                        shoppingBasketList.Add(shoppingBasket);
                    }
                }
                else
                {
                    shoppingBasketList = nhibernateSession.QueryOver<Shoppingbasket>()
                    .Where(x => x.Users == user)
                    .List();
                }
                orderIdList = new int[shoppingBasketList.Count];
                int i = 0;
                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        foreach (Shoppingbasket shoppingBasket in shoppingBasketList)
                        {
                            nhibernateSession.Refresh(shoppingBasket.Product);
                            if (!shoppingBasket.Product.UseYN)
                            {
                                tx.Rollback();
                                return Json(new { result = "FAILURE", msg = shoppingBasket.Product.Name + "은 마감된 상품입니다." }, JsonRequestBehavior.AllowGet);
                            }
                            if (shoppingBasket.Product.Quantity < shoppingBasket.Quantity)
                            {
                                tx.Rollback();
                                return Json(new { result = "FAILURE", msg = shoppingBasket.Product.Name + "의 재고가 부족합니다." }, JsonRequestBehavior.AllowGet);
                            }

                            Orders order = new Orders
                            {
                                Product = shoppingBasket.Product,
                                Quantity = (int)shoppingBasket.Quantity,
                                Users = user,
                                ReservationDate = DateTime.Now.ToString("yyyyMMddHHmmss")
                            };
                            nhibernateSession.Save(order);
                            nhibernateSession.Delete(shoppingBasket);
                            orderIdList[i++] = order.Id;
                        }
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        SessionProvider.Instance.CloseSession();
                        throw te;
                    }
                }
                return Json(new { result = "SUCCESS", data = new { orderIdList = orderIdList } }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult InsertOrdersDirectly(string token, int? productId, int? quantity)
        {
            try
            {
                if (productId == null) return Json(new { result = "FAILURE", msg = "productId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (quantity == null) return Json(new { result = "FAILURE", msg = "quantity가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Users user = nhibernateSession.QueryOver<Users>()
                    .Where(x => x.Token == token)
                    .List()
                    .FirstOrDefault();

                Product product = nhibernateSession.Load<Product>(productId);
                if (product == null) return Json(new { result = "FAILURE", msg = "Id가 " + productId + "인 상품이 없습니다." }, JsonRequestBehavior.AllowGet);
                if (!product.UseYN)
                {
                    return Json(new { result = "FAILURE", msg = product.Name + "은 마감된 상품입니다." }, JsonRequestBehavior.AllowGet);
                }
                nhibernateSession.Refresh(product);
                if (product.Quantity < quantity) return Json(new { result = "FAILURE", msg = product.Name + "의 재고가 부족합니다." }, JsonRequestBehavior.AllowGet);
                Orders order = new Orders
                {
                    Product = product,
                    Quantity = (int)quantity,
                    Users = user,
                    ReservationDate = DateTime.Now.ToString("yyyyMMddHHmmss")
                };
                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        nhibernateSession.Save(order);
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        SessionProvider.Instance.CloseSession();
                        throw te;
                    }
                }
                return Json(new { result = "SUCCESS", data = new { orderId = order.Id } }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult ConfirmOrders(string token, int? orderId)
        {
            try
            {
                if (orderId == null) return Json(new { result = "FAILURE", msg = "orderId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);
                
                Orders order = nhibernateSession.Get<Orders>(orderId);
                if (order.ApprovalYN==TRUE)
                {
                    return Json(new { result = "FAILURE", msg = "이미 승인된 주문입니다." }, JsonRequestBehavior.AllowGet);
                }
                order.ApprovalYN = TRUE;
                order.ApprovalDate = DateTime.Now.ToString("yyyyMMddHHmmss");
                order.RejectMessage = null;
                nhibernateSession.Refresh(order.Product);
                if (!order.Product.UseYN)
                {
                    return Json(new { result = "FAILURE", msg = order.Product.Name + "은 마감된 상품입니다." }, JsonRequestBehavior.AllowGet);
                }
                if (order.Product.Quantity < order.Quantity)
                {
                    return Json(new { result = "FAILURE", msg = order.Product.Name + "의 재고가 부족합니다." }, JsonRequestBehavior.AllowGet);
                }
                else
                {
                    order.Product.Quantity -= (int)order.Quantity;
                }
                
                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        nhibernateSession.Update(order);
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        SessionProvider.Instance.CloseSession();
                        throw te;
                    }
                }

                return Json(new { result = "SUCCESS", data = new { ApprovalDate = order.ApprovalDate } }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult CancelOrders(string token, int? orderId)
        {
            try
            {
                //트랜잭션
                if (orderId == null) return Json(new { result = "FAILURE", msg = "orderId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Orders order = nhibernateSession.Get<Orders>(orderId);
                if(order == null)
                    return Json(new { result = "FAILURE", msg = "id가 " + orderId + "인 주문이 없습니다." }, JsonRequestBehavior.AllowGet);
                if(order.ApprovalYN == TRUE)
                    return Json(new { result = "FAILURE", msg = "승인되었으므로 취소할 수 없습니다." }, JsonRequestBehavior.AllowGet);                
                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        if(order.ApprovalYN != FALSE) order.Product.Quantity += (int)order.Quantity; // 승인거부된 것이 아니라면 재고를 늘린다.
                        nhibernateSession.Update(order.Product);
                        nhibernateSession.Delete(order);
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        throw te;
                    }
                }

                return Json(new { result = "SUCCESS" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult RejectOrders(string token, int? orderId, string rejectMessage)
        {
            try
            {
                if (orderId == null) return Json(new { result = "FAILURE", msg = "orderId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Orders order = nhibernateSession.Get<Orders>(orderId);
                order.ApprovalYN = FALSE;
                order.ApprovalDate = null;
                order.RejectMessage = rejectMessage;
                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {
                        order.Product.Quantity += (int)order.Quantity; // 재고를 늘린다.
                        nhibernateSession.Update(order.Product);
                        nhibernateSession.Update(order);
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        SessionProvider.Instance.CloseSession();
                        throw te;
                    }
                }
                return Json(new { result = "SUCCESS" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult ConfirmReceipt(string token, int? orderId)
        {
            try
            {
                if (orderId == null) return Json(new { result = "FAILURE", msg = "orderId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                Orders order = nhibernateSession.Get<Orders>(orderId);
                if (order == null) return Json(new { result = "FAILURE", msg = "id가 " + orderId + "인 주문이 존재하지 않습니다." }, JsonRequestBehavior.AllowGet);
                if(!(order.ApprovalYN == TRUE))
                    return Json(new { result = "FAILURE", msg = "주문이 승인되지 않았습니다." }, JsonRequestBehavior.AllowGet);
                if(order.ReceiptDate != null)
                    return Json(new { result = "FAILURE", msg = "이미 수령하였습니다. (수령시간:" + order.ReceiptDate + ")" }, JsonRequestBehavior.AllowGet);    
                Product product = order.Product;
                Standardproduct standardProduct = product.Standardproduct;
                string now = DateTime.Now.ToString("yyyyMMddHHmmss");
                order.ReceiptDate = now;

                Salehistory saleHistory = new Salehistory
                {
                    Orders = order,
                    ProductPrice = product.Price,
                    ProductUnitQuantity = product.UnitQuantity,
                    Quantity = order.Quantity,
                    StandardProductPrice = standardProduct.Price,
                    StandardProductUnit = standardProduct.Unit,
                    StandardProductUnitQuantity = standardProduct.UnitQuantity,
                    SaleDate = now
                };

                #region 구매통계
                int myPrice = product.Price * order.Quantity;
                int othersPrice = (int)(Math.Round((decimal)(standardProduct.Price * product.UnitQuantity / standardProduct.UnitQuantity), 0, MidpointRounding.AwayFromZero)); // 반올림
                    
                Purchasestatistics purchaseStiatics = nhibernateSession.QueryOver<Purchasestatistics>()                    
                    .Where(x => x.Users == order.Users)
                    .List()
                    .FirstOrDefault();
                if (purchaseStiatics == null) //구매통계 새로 생성
                {
                    purchaseStiatics = new Purchasestatistics
                    {
                        Mypricesum = myPrice,
                        Otherspricesum = othersPrice,
                        Users = order.Users
                    };
                }
                else // 기존 구매통계에 합산
                {
                    purchaseStiatics.Mypricesum += myPrice;
                    purchaseStiatics.Otherspricesum += othersPrice;
                }
                #endregion

                #region 판매통계
                int price = product.Price * order.Quantity;
                string currentYearMonth = DateTime.Now.ToString("yyyyMM");
                Salestatistics saleStatistics = nhibernateSession.QueryOver<Salestatistics>()
                    .Where(x => x.Store == product.Store)
                    .Where(x => x.YearMonth == currentYearMonth)
                    .List()
                    .FirstOrDefault();
                if (saleStatistics == null) //판매통계 새로 생성
                {
                    saleStatistics = new Salestatistics
                    {
                        Customersum = 1,
                        Pricesum = price,
                        Store = product.Store,
                        YearMonth = currentYearMonth
                    };
                }
                else // 기존 판매통계에 합산
                {
                    saleStatistics.Customersum += 1;
                    saleStatistics.Pricesum += price;
                }                

                #endregion

                using (var tx = nhibernateSession.BeginTransaction())
                {
                    try
                    {                      
                        nhibernateSession.Update(order);
                        nhibernateSession.Save(saleHistory);
                        nhibernateSession.SaveOrUpdate(purchaseStiatics);
                        nhibernateSession.SaveOrUpdate(saleStatistics);
                        nhibernateSession.Flush();
                        tx.Commit();
                    }
                    catch (Exception te)
                    {
                        tx.Rollback();
                        SessionProvider.Instance.CloseSession();
                        throw te;
                    }
                }
                return Json(new { result = "SUCCESS", data = new { saleHistoryId = saleHistory.Id } }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetOrderListOfCustomer(string token, int? pageSize, int? pageNum)
        {
            try
            {
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);
                
                Users user = nhibernateSession.QueryOver<Users>()
                    .Where(x => x.Token == token)
                    .List()
                    .FirstOrDefault();
                IQueryOver<Orders, Orders> queryOver = nhibernateSession.QueryOver<Orders>()
                    .Where(x => x.Users == user)
                    .OrderBy(x => x.ReservationDate).Desc;
                if (pageSize != null && pageNum != null)
                {
                    int pageSize1 = pageSize ?? 0;
                    int pageNum1 = pageNum ?? 0;
                    queryOver.Skip(pageNum1 * pageSize1).Take(pageSize1);
                }
                IList<Orders> orderList = queryOver.List<Orders>();
                return Json(new { result = "SUCCESS", data = orderList }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetOrderListOfTrader(string token, int? storeId, int? pageSize, int? pageNum)
        {
            try
            {
                if (storeId == null) return Json(new { result = "FAILURE", msg = "storeId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);
                
                Store store = nhibernateSession.QueryOver<Store>()
                    .Where(x => x.Id == storeId)
                    .List()
                    .FirstOrDefault();
                if(store == null) return Json(new { result = "FAILURE", msg = "Id가 " + storeId + "인 상점이 없습니다." }, JsonRequestBehavior.AllowGet);
                
                List<Product> productList = nhibernateSession.QueryOver<Product>()
                    .Where(x => x.Store == store)
                    .List() as List<Product>;
                
                Orders orderAlias = null;
                IQueryOver<Orders, Orders> queryOver = nhibernateSession.QueryOver<Orders>(() => orderAlias)
                    .WhereRestrictionOn(() => orderAlias.Product).IsIn(productList)
                    .Where(x => x.ApprovalYN == TRUE || x.ApprovalYN == null) // 승인거부한 주문 제외
                    .Where(x => x.ReceiptDate == null) // 수령완료한 주문 제외
                    .OrderBy(x => x.ReservationDate).Desc;

                if (pageSize != null && pageNum != null)
                {
                    int pageSize1 = pageSize ?? 0;
                    int pageNum1 = pageNum ?? 0;
                    queryOver.Skip(pageNum1 * pageSize1).Take(pageSize1);
                }
                IList<Orders> orderList = queryOver.List<Orders>();
                return Json(new { result = "SUCCESS", data = orderList }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }
        
        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetTotalPurchaseInformation(string token)
        {
            try
            {
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);


                Users user = nhibernateSession.QueryOver<Users>()
                   .Where(x => x.Token == token)
                   .List()
                   .FirstOrDefault();
                Purchasestatistics purchaseStatistics = nhibernateSession.QueryOver<Purchasestatistics>()
                    .Where(x => x.Users == user)
                    .List()
                    .FirstOrDefault();
                if (purchaseStatistics == null) // 구매기록 없을 때
                {
                    return Json(new
                    {
                        result = "SUCCESS",
                        data = new Purchasestatistics { Id = -1, Mypricesum = 0, Otherspricesum = 0, Users = user }
                    }, JsonRequestBehavior.AllowGet);
                }
                return Json(new { result = "SUCCESS", data = purchaseStatistics }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetTotalSaleInformation(string token, int? storeId, string fromYearMonth, string toYearMonth)
        {
            try
            {
                if (storeId == null) return Json(new { result = "FAILURE", msg = "storeId가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);
                DateTime fromYearMonthDate = new DateTime();
                DateTime toYearMonthDate = new DateTime();
                if (fromYearMonth != null && toYearMonth != null)
                {
                    try
                    {
                        fromYearMonthDate = DateTime.ParseExact(fromYearMonth, "yyyyMM", CultureInfo.InvariantCulture);
                        toYearMonthDate = DateTime.ParseExact(toYearMonth, "yyyyMM", CultureInfo.InvariantCulture);
                    }
                    catch
                    {
                        return Json(new { result = "FAILURE", msg = "fromYearMonth 또는 toYearMonth가 yyyyMM타입이 아닙니다." }, JsonRequestBehavior.AllowGet);
                    }
                }
                Store store = nhibernateSession.Get<Store>(storeId);
                if (store == null) return Json(new { result = "FAILURE", msg = "id가 " + storeId + "인 상점이 없습니다." }, JsonRequestBehavior.AllowGet);
                IList<Salestatistics> saleStatisticsList = nhibernateSession.QueryOver<Salestatistics>()
                    .Where(x => x.Store == store)
                    .List();
                if (saleStatisticsList == null) //판매기록 없을 때
                {
                    return Json(new { result = "SUCCESS", data = new { priceSum = 0, customerSum = 0 } }, JsonRequestBehavior.AllowGet);
                }

                int priceSum = 0;
                int customerSum = 0;
                foreach (Salestatistics saleStatistics in saleStatisticsList)
                {
                    DateTime yearMonthDate = DateTime.ParseExact(saleStatistics.YearMonth, "yyyyMM", CultureInfo.InvariantCulture);
                    if (fromYearMonth == null || toYearMonth == null || (yearMonthDate >= fromYearMonthDate && yearMonthDate <= toYearMonthDate))
                    {
                        priceSum += saleStatistics.Pricesum;
                        customerSum += saleStatistics.Customersum;
                    }
                }
                return Json(new { result = "SUCCESS", data = new { priceSum = priceSum, customerSum = customerSum } }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        [AllowAnonymous]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public JsonResult GetAltanativeGoodsComment(string token, int? price)
        {
            try
            {
                if (price == null) return Json(new { result = "FAILURE", msg = "price가 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (token == null) return Json(new { result = "FAILURE", msg = "token이 입력되어야 합니다." }, JsonRequestBehavior.AllowGet);
                if (!AuthUtil.IsAuthorized(token)) return Json(new { result = "FAILURE", msg = "인증되지 않은 접근입니다." }, JsonRequestBehavior.AllowGet);

                IList<Altanativegoods> altanativeGoodsList = nhibernateSession.QueryOver<Altanativegoods>().List();
                foreach (Altanativegoods altanativeGoods in altanativeGoodsList)
                {
                    if (price >= altanativeGoods.MinPrice && price < altanativeGoods.MaxPrice)
                    {
                        return Json(new { result = "SUCCESS", data = altanativeGoods.Comments}, JsonRequestBehavior.AllowGet);
                    }
                }
                return Json(new { result = "SUCCESS", data = "최고입니다!" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                if (e.InnerException == null) return Json(new { result = "FAILURE", msg = e.Message }, JsonRequestBehavior.AllowGet);
                else return Json(new { result = "FAILURE", msg = e.InnerException.Message }, JsonRequestBehavior.AllowGet);
            }
        }
    }
}
